package com.share.example.stock.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.share.common.utils.CollectionUtil;
import com.share.common.utils.DateUtil;
import com.share.common.utils.ThreadUtil;
import com.share.example.stock.enums.StockStatusEnum;
import com.share.example.stock.enums.StrategyEnum;
import com.share.example.stock.mapper.StockBaseInfoMapper;
import com.share.example.stock.mapper.StockMinPriceMapper;
import com.share.example.stock.model.ak.OpenCloseLowHigh;
import com.share.example.stock.model.ak.ZhASpotEm;
import com.share.example.stock.model.db.StockBaseInfo;
import com.share.example.stock.model.db.StockMinPrice;
import com.share.example.stock.model.vo.CodePirceO;
import com.share.example.stock.service.*;
import com.share.example.stock.utils.CalcUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 目标地址: http://quote.eastmoney.com/concept/sh603777.html?from=classic
 * 描述: 东方财富-股票行情-盘前数据
 * 限量: 单次返回指定当前交易日的股票分钟数据, 包含盘前分钟数据
 * symbol	str	symbol="000001"; 股票代码
 * start_date	str	start_date="09:00:00"; 时间; 默认返回所有数据
 * end_date	str	end_date="15:40:00"; 时间; 默认返回所有数据  服务实现类
 * </p>
 *
 * @author author
 * @since 2023-06-10
 */
@Slf4j
@Service
public class StockMinPriceServiceImpl extends ServiceImpl<StockMinPriceMapper, StockMinPrice> implements IStockMinPriceService {
    @Autowired
    private AkService akService;

    @Autowired
    private SendMessage sendMessage;

    @Autowired
    private IUserService userService;

    @Autowired
    private StrategyService strategyService;

    @Resource
    private StockMinPriceMapper stockMinPriceMapper;

    @Resource
    private StockBaseInfoMapper stockBaseInfoMapper;


    @Override
    public List<StockMinPrice> downMin() {
        List<StockMinPrice> insertList = new LinkedList<>();
        List<ZhASpotEm> zhASpotEms = akService.stock_zh_a_spot_em();

        Date date = new Date();
        String strDate = DateUtil.getDate(date);
        String strTime = DateUtil.getTime(date);
        String tradeDate = DateUtil.getDate();
        for (ZhASpotEm item : zhASpotEms) {
            StockMinPrice record = new StockMinPrice();
            record.setCode(item.getCode());
            record.setVolume(item.getVolume());
            record.setAmount(item.getAmount());

            record.setHigh(item.getHigh());
            record.setLow(item.getLow());
            record.setOpen(item.getOpen());
            record.setClose(item.getLastPrice());
            record.setYclose(item.getYclose());

            record.setDate(strDate);
            record.setTime(strTime);

            //价格均值计算
            OpenCloseLowHigh cp = CalcUtil.calcPrice(item.getOpen(), item.getLastPrice(), item.getLow(), item.getHigh());
            record.setHlO(cp.getHighSlowDopen());
            record.setCoO(cp.getCloseSopenDopen());
            record.setHl(cp.getHighSlow());
            record.setCo(cp.getCloseSopen());
            record.setClHl(cp.getCloseSlowDhighSlow());
            record.setOlHl(cp.getOpenSlowDhighSlow());
            record.setHcHl(cp.getHighScloseDhighSlow());
            record.setHoHl(cp.getHighSopenDhighSlow());
            record.setAvgHl(cp.getAvghighSlow());
            record.setAvgOc(cp.getAvgOpenclose());

            //最佳到记录
            insertList.add(record);

            //更新总表的信息---使用实时数据
            StockBaseInfo baseInfo = new StockBaseInfo();
            baseInfo.setLastPriceRate(item.getRiseOrFallRate());
            baseInfo.setLastPrice(item.getLastPrice());
            baseInfo.setLastVolume(item.getVolume());
            baseInfo.setLastPriceUpdateTime(date);
            baseInfo.setCode(item.getCode());
            if (item.getHigh() == null && item.getLow() == null && item.getVolume() == null) {
                // 无数据也不能设置为空,否则会出现问题的
                //baseInfo.setStatus(StockStatusEnum.OTHER.getCode()); //僵尸状态
            }

            //10:20点之前检测一次即可
            if ("10:20:00".compareTo(strTime) >= 0) {
                //st 检测
                if (CalcUtil.isExit(item.getName())) {
                    baseInfo.setStatus(StockStatusEnum.ST.getCode());//设置为ST
                }

                // 退出检测
                if (CalcUtil.isExit(item.getName())) {
                    baseInfo.setStatus(StockStatusEnum.EXIT.getCode());//设置为退出
                }
            }

            ThreadUtil.execute(() -> stockBaseInfoMapper.updateByCode(baseInfo)); //异步执行
        }

        //3.分钟数据入库-----不需要删除
        if (insertList.size() > 0) {
            //3.数据去重
            stockMinPriceMapper.deleteByDate(tradeDate);

            int batchId = 0;
            List<List<StockMinPrice>> lists = CollectionUtil.splitList(insertList, 500);
            for (List<StockMinPrice> itemList : lists) {
                log.info("批量插入batchId={},size={}", ++batchId, itemList.size());
                int counti = stockMinPriceMapper.insertbatch(itemList);
            }
        }

        return insertList;
    }

    @Override
    public int dowm_stock_min_monitor() {
        List<CodePirceO> msgList = new LinkedList<>();
        List<CodePirceO> collectMsgList = new LinkedList<>();

        List<ZhASpotEm> zhASpotEms = akService.stock_zh_a_spot_em();
        Set<String> codes = userService.listAllCollect();

        for (ZhASpotEm item : zhASpotEms) {
            //价格均值计算
            OpenCloseLowHigh cp = CalcUtil.calcPrice(item.getOpen(), item.getLastPrice(), item.getLow(), item.getHigh());
            boolean pass = CalcUtil.fiterCloseSopenDopenU(cp, 0.08d);//高于8%的
            if (pass) {
                CodePirceO vo = new CodePirceO();
                vo.setCode(item.getCode());
                vo.setPrice(item.getLastPrice());
                vo.setOther(cp.getCloseSopenDopen());
                msgList.add(vo);
            }

            //收藏处理
            if (codes.contains(item.getCode())) {
                boolean pass1 = CalcUtil.fiterCloseSopenDopenU(cp, 0.03d);//高于8%的
                if (pass1) {
                    CodePirceO vo = new CodePirceO();
                    vo.setCode(item.getCode());
                    vo.setPrice(item.getLastPrice());
                    vo.setOther(cp.getCloseSopenDopen());
                    collectMsgList.add(vo);
                }
            }
        }

        //2.分钟数据监控发送到钉钉or邮件
        ThreadUtil.execute(() -> sendMessage.sendMSg2DingDingOrEmail(StrategyEnum.RATE_U8, msgList)); //异步执行

        //2.1 收藏的票数据
        ThreadUtil.execute(() -> sendMessage.sendMSg2DingDingOrEmail(StrategyEnum.COLLECT_3, collectMsgList)); //异步执行

        //3.当天数据异步处理
        Date today = new Date();
        ThreadUtil.execute(() -> strategyService.saveOrUpdateOnedayStrategy(StrategyEnum.RATE_U8.getCode(), today, msgList));

        return msgList.size();
    }

    //删除历史数据
    @Override
    public int deleteHistoryByDay(String histDate) {
        QueryWrapper<StockMinPrice> queryWrapper = new QueryWrapper();
        queryWrapper.lt("date", histDate);  //小于指定日期的
        return stockMinPriceMapper.delete(queryWrapper);
    }

    @Override
    public List<StockMinPrice> listByCode(String code) {
        QueryWrapper<StockMinPrice> queryWrapper = new QueryWrapper();
        queryWrapper.eq("code", code);
        queryWrapper.orderByDesc("id");
        queryWrapper.last("limit 30");
        return stockMinPriceMapper.selectList(queryWrapper);
    }
}
